//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================



using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

using System.Drawing.Design;
using System.Workflow.Runtime.Hosting;
using System.Xml;
using System.Collections.Generic;
using System.Text;
using System.IO;

using Shp.Runtime.Services;

namespace LitwareHR.Recruiting.Workflows.Activities
{
    public partial class WorkflowFactoryActivity : Activity
    {
        static public readonly DependencyProperty InstanceIdProperty = DependencyProperty.Register("InstanceId", typeof(Guid), typeof(WorkflowFactoryActivity));
        static public readonly DependencyProperty ParametersProperty = DependencyProperty.Register("Parameters", typeof(Dictionary<string, object>), typeof(WorkflowFactoryActivity), new PropertyMetadata(DependencyPropertyOptions.ReadOnly, new Attribute[] {new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)}));
        static public readonly DependencyProperty TargetWorkflowProperty = DependencyProperty.Register("TargetWorkflow", typeof(Guid), typeof(WorkflowFactoryActivity), new PropertyMetadata(null));
        static public DependencyProperty InvokedEvent = DependencyProperty.Register("Invoked", typeof(EventHandler), typeof(WorkflowFactoryActivity));
        static public DependencyProperty InvokingEvent = DependencyProperty.Register("Invoking", typeof(EventHandler), typeof(WorkflowFactoryActivity));

        public WorkflowFactoryActivity()
        {
            base.SetReadOnlyPropertyValue(ParametersProperty, new Dictionary<string, object>());
            InitializeComponent();
        }

        [Description("This event will be invoked after the target workflow is invoked.")]
        [Category("Handlers")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public event EventHandler Invoked
        {
            add
            {
                base.AddHandler(InvokedEvent, value);
            }
            remove
            {
                base.RemoveHandler(InvokedEvent, value);
            }
        }

        [Description("This event will be invoked before the target workflow is invoked.")]
        [Category("Handlers")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public event EventHandler Invoking
        {
            add
            {
                base.AddHandler(InvokingEvent, value);
            }
            remove
            {
                base.RemoveHandler(InvokingEvent, value);
            }
        }

        [Category("Activity")]
        [Description("InstanceId of workflow that is invoked")]
        public Guid InstanceId
        {
            get
            {
                return (Guid) base.GetValue(InstanceIdProperty);
            }
            set
            {
                base.SetValue(InstanceIdProperty, value);
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Browsable(false)]
        public Dictionary<string, object> Parameters
        {
            get
            {
                return base.GetValue(ParametersProperty) as Dictionary<string, object>;
            }
        }

        [Category("Activity")]
        [Description("Type of workflow to invoke (Guid)")]
        public Guid TargetWorkflow
        {
            get
            {
                return (Guid) base.GetValue(TargetWorkflowProperty);
            }
            set
            {
                base.SetValue(TargetWorkflowProperty, value);
            }
        }

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            this.RaiseEvent(InvokingEvent, this, new EventArgs());

            if (TargetWorkflow == null || TargetWorkflow.Equals(Guid.Empty))
            {
                throw new InvalidOperationException("TargetWorkflow property must be set to a valid Type that derives from Activity.");
            }

            string str = WorkflowLogic.GetWorkflowDef(TargetWorkflow).Xoml;
            TextReader sr = new StringReader(str);
            XmlReader xomlReader = XmlReader.Create(sr);

            WorkflowFactoryRuntimeService startWorkflowService = executionContext.GetService<WorkflowFactoryRuntimeService>();

            Guid instanceId = startWorkflowService.StartWorkflow(xomlReader, null, this.Parameters);

            base.SetValue(InstanceIdProperty, instanceId);
            this.RaiseEvent(InvokedEvent, this, new EventArgs());

            return ActivityExecutionStatus.Closed;
        }
    }
}
